import {Component, OnInit, AfterViewInit} from '@angular/core';

import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ'
import {Tile} from 'ol';
import {Fill, Stroke, Style} from 'ol/style';
import {ActivatedRoute, ParamMap} from '@angular/router';
import {GeoJSON} from 'ol/format';
import {Vector as VectorSource} from 'ol/source';
import {Vector as VectorLayer} from 'ol/layer';
import {HttpService} from '@kylin/http';
import OSM from 'ol/source/OSM';
import {MapService} from './map.service';
import Overlay from 'ol/Overlay';
import {fromLonLat} from 'ol/proj';

@Component({
    templateUrl: './map.component.html',
    styleUrls: ['./map.component.less']
})

export class MapComponent implements OnInit, AfterViewInit {
    map: Map;
    switchLayerMenu = false;
    administrativeLayerMenu = false;
    administrativeLayerButtons = {province: false, city: false, counties: false}
    layers = {};
    hasMapLegend = false;
    hasMapLegendButton = true;
    utilsData = null;
    sidebarMenuList: Array<any>;
    sideMenuVisibility = false;
    private _nzCollapsed = true;

    get nzCollapsed() {
        return this._nzCollapsed;
    }

    set nzCollapsed(value) {
        this._nzCollapsed = value;
        this.mapService.$changeNzCollapsedObservable(value);
    }

    constructor(private activatedRoute: ActivatedRoute,
                private Http: HttpService,
                private mapService: MapService
    ) {

    }

    ngOnInit() {
        this.sidebarMenuList = this.mapService.getSidebarMenuData();
        this.init();
        this.turnOnByParams();
    }

    ngAfterViewInit(): void {
        this.mapService.nzCollapsedObservable.subscribe((value) => {
            setTimeout(() => {
                this.resetMapSize(value);
            }, 0)
        })
    }

    private resetMapSize(value) {
        const target = document.getElementById('map');
        const height = +target.offsetHeight;
        const width = +target.offsetWidth;
        this.map.setSize([width, height]);
    }

    getOSMLayer() {
        return new TileLayer({
            source: new OSM()
        })
    }

    private init() {
        this.map = new Map({
            layers: [
                new TileLayer({
                    source: new XYZ({
                        crossOrigin: 'anonymous',
                        url: `http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i380072576!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0`
                    })
                })
            ],
            target: 'map',
            view: new View({
                zoom: 4,
                center: fromLonLat([108.943904, 34.319323])
            })
        });
    }

    rotateNorth() {
        const viewAnimate = this.map['getView']();
        viewAnimate.animate({
            rotation: viewAnimate.getRotation() + Math.PI / 2
        })
    }

    switchLayer(type = 'default') {
        const layers = {
            default: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i380072576!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0',
            satellite: 'http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}',
            topographic: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i380072576!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0!5m1!1e0'
        }
        const baseLayer = this.map.getLayers().item(0);
        baseLayer['setSource'](
            new XYZ({
                crossOrigin: 'anonymous',
                url: layers[type] || layers['default']
            })
        )
    }

    administrativeLayer($event, type: string) {
        const types = {
            province: 'http://121.41.65.118:8089/MapService/getGdp?x={x}&y={y}&z={z}&s=1',
            city: 'http://121.41.65.118:8089/MapService/getGdp?x={x}&y={y}&z={z}&s=2',
            counties: 'http://121.41.65.118:8089/MapService/getGdp?x={x}&y={y}&z={z}&s=3'
        }
        if ($event) {
            this.addLayer(type, types[type], {opacity: 1});
        } else {
            this.removeLayer(type);
        }
    }

    private addLayer(name: string, url: string, options?: { opacity: number }) {
        if (this.layers[name]) {
            return;
        }
        this.layers[name] = new TileLayer({
            source: new XYZ({
                crossOrigin: 'anonymous',
                url: url
            }),
            opacity: options.opacity || 1
        })
        this.map.addLayer(this.layers[name]);
    }

    private removeLayer(name: string) {
        if (this.layers[name]) {
            this.map.removeLayer(this.layers[name]);
            delete this.layers[name];
        }
    }

    mapLegendClose($event) {
        this.hasMapLegend = $event;
        this.hasMapLegendButton = true;
    }

    turnOnByParams() {
        this.activatedRoute.queryParams.subscribe((params: ParamMap) => {
            this.utilsData = params;
        })
    }
}
